
import random
import re
from datetime import datetime

from flask import current_app, jsonify
from flask import json
from flask import make_response
from flask import request
from flask import session

from info import constants, db
from info import redis_store
from info.libs.yuntongxun.sms import CCP
from info.models import User
from info.utils.captcha.captcha import captcha
from info.utils.response_code import RET
from . import passport_blue
"""
"""""
# 验证模块的视图函数
# 发送图片验证码的视图函数
# 请求方式为get

@passport_blue.route('/image_code')
def send_image_code():

    """
    生成图片验证码，返回
    1.浏览器携带参数uuid（随机字符串）请求,接受浏览器请求，获取参数
    2.生成验证码
    3.保存到redis（key(uuid)=验证码）
    4.返回生成的验证码
    """
    # 浏览器携带参数uuid（随机字符串）请求, 接受浏览器请求，获取参数
    data = request.args
    cur_id = data.get('cur_id')
    per_id = data.get('per_id')

    # 生成图片验证码
    name,text,image_data = captcha.generate_captcha()
    # 保存到redis（key(uuid) = 验证码）
    try:
        redis_store.set("image_code:%s"%cur_id,text,constants.IMAGE_CODE_REDIS_EXPIRES)
        # 确保只储存上一次的验证码，其他的都是失效状态，不需要保留
        if per_id:
            redis_store.delete("image_code:%s"%per_id)
    except Exception as e:
        current_app.logger.error(e)

# 返回生成的验证码
    resp = make_response(image_data)
    resp.headers['Content-Type']='img/jpg'
    return resp



# 发送短信验证码
@passport_blue.route('/sms_code',methods=['post'])
def send_sms_code():

    """
    1.接受参数,获取图片验证码，手机号
    2.判断参数不为空
    3.判断手机号是否合法
    4.判断验证码A与储存的验证码B,是否相等
    5,返回状态
    :return:
    """
    # 接受参数, 获取图片验证码，手机号
    # json_data = request.data
    # dict_data = json.loads(json_data)
    dict_data=request.json
    mobile = dict_data.get('mobile')
    image_code = dict_data.get('image_code')
    image_code_id = dict_data.get('image_code_id')
    # 判断参数不为空
    if not all ([mobile,image_code,image_code_id]):
        return jsonify(erron=RET.PARAMERR,errmsg='参数不全')
    # 判断手机号是否合法
    if not re.match("^1[345678]\\d{9}$",mobile):
        return jsonify(erron=RET.DATAERR ,errmsg='手机号错误')
    # 判断验证码A与储存的验证码B, 是否相等
    try:
        redis_image_code = redis_store.get("image_code:%s"%image_code_id)
    except Exception as e:
        current_app.logger.error(e)
    # 判断是否过期
    if not redis_image_code:
        return jsonify(erron=RET.DATAERR ,errmsg='图片验证码过期')

    # 判断是否正确
    if redis_image_code.lower() !=image_code.lower():
        return jsonify(erron=RET.DATAERR ,errmsg='图片验证码填写错误')
    try:
        redis_store.delete("image_code:%s"%image_code_id)
    except Exception as e:
        current_app.logger.error(e)
    # 随机生成验证码
    sms_code ="%06d"%random.randint(0, 999999)
    # 发送信息，调用send_template_sms
    # ccp =CCP()
    # result = ccp.send_template_sms(mobile, [sms_code, 5], 1)
    # if result == -1:
    #     return jsonify(errno=RET.THIRDERR,errmsg="短信发送失败")
    current_app.logger.debug("短信验证码 = %s" % sms_code)

    # 保存验证码到redis中，用于后面的注册
    try:
        redis_store.set('sms_code:%s'%mobile,sms_code,constants.SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)

    # 返回状态
    return  jsonify(erron=RET.OK ,errmsg='发送成功')

# 添加注册功能
@passport_blue.route('/register',methods=['post'])
def register():
    """
    1.接受参数
    参数：手机号，短信验证码，密码
    2.校验参数
    3.建用户对象，存用户信息到mysql
    4.用户信息存到session
    5.返回状态
    :return:
    """
    # 接受参数
    dict_data =request.json
    mobile = dict_data.get('mobile')
    sms_code = dict_data.get('sms_code')
    password = dict_data.get('password')
    # 判断参数不为空
    if not all([mobile, sms_code,password]):
        return jsonify(erron=RET.PARAMERR, errmsg='参数不全')
    # 判断手机号是否合法
    if not re.match("^1[345678]\\d{9}$", mobile):
        return jsonify(erron=RET.DATAERR, errmsg='手机号错误')
        # 判断短信验证码A与储存的短信验证码B, 是否相等
    redis_sms_code = redis_store.get('sms_code:%s' % mobile)
    try:
        redis_sms_code = redis_store.get('sms_code:%s' % mobile)
    except Exception as e:
        current_app.logger.error(e)
        # 判断是否过期
    if not redis_sms_code:
        return jsonify(erron=RET.DATAERR, errmsg='短信验证码过期')
    # 判断是否正确
    if redis_sms_code != sms_code:
        return jsonify(erron=RET.DATAERR, errmsg='短信验证码填写错误')
    #建用户对象，存用户信息到mysql
    user=User()
    user.nick_name = mobile
    # user.password_hash = password  # 没有加密的密码
    user.mobile=mobile
    # 通过属性加密操作,@property属性设置值，password()中有加密操作
    user.password =password
    # user.last_login= datetime.now()  # 获取当前系统时间
    # 保存到数据库
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DATAERR, errmsg="数据保存错误")
    # 使用session记录用户状态
    session['user_id']=user.id
    session['nick_name']=user.nick_name
    session['mobile']=user.mobile
    # 返回注册状态到前端页面
    return jsonify(errno=RET.OK ,errmsg='发送成功')

# 添加登录功能
@passport_blue.route('/login',methods=['post'])
def login():
    """
    1.接受参数
    参数：手机号，密码
    2.校验参数
    3.保存到session
    4.返回状态
    :return:
    """
    dict_data = request.get_json()
    mobile= dict_data.get('mobile')
    password = dict_data.get('password')
    # 校验参数
    if not all([mobile, password]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不全")

    # 判断手机号格式是否正确
    if not re.match('1[356789]\\d{9}', mobile):
        return jsonify(errno=RET.DATAERR, errmsg="手机号错误")
    # 判断是否正确
    try:
        user=User.query.filter(User.mobile == mobile).first()

    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询用户对象失败")
    if not user:
        return jsonify(errno=RET.NODATA, errmsg="该用户不存在")
    # 判断密码是否正确，因为密码存的时候使用加密存储，不可能解密，只能把这个密码加密比较加密
    # 是否一致
    if not user.check_passowrd(password):
        return jsonify(errno=RET.DATAERR, errmsg="密码错误")
    # 保存用户登录状态
    session['user_id']=user.id
    session['mobile']=user.mobile
    session['nick_name']=user.nick_name
    # 每次登录都要记录最新的登录时间,需要提交
    user.last_login = datetime.now()
    # 更改后提交，也可以使用数据库的配置来完成这步，当监测到数据变化，就自动更新
    # 这样就不用每次更改数据都要提交一次，简化代码
    # db.session.commit()

    # 返回状态到前端页面
    return jsonify(errno=RET.OK, errmsg="OK")

# 添加退出功能
@passport_blue.route('/logout',methods=['delete'])
def logout():
    """
    清除session，重新加载页面

    :return:
    """
    session.pop("user_id", None)
    session.pop("nick_name", None)
    session.pop("mobile", None)
    session.pop("is_admin", None)

    return jsonify(errno=RET.OK,errmsg='退出成功')




